#pragma once
#include <iostream>
#include <memory.h>
#include "Connection.hpp"
#include "Common.hpp"
#include "Socket.hpp"
#include "Log.hpp"
#include "Channel.hpp"

using namespace std;
using namespace SocketModule;
using namespace LogModule;

//获取新连接
class Listener : public Connection
{
public:
    Listener(int port=defaultport)
    :_port(port)
    ,_listensock(make_unique<TcpSocket>())
    {
        _listensock->BuildTcpSocketMethod(_port);   //注意这里已经获取了listen套接字
        SetEvent(EPOLLIN | EPOLLET);                //关心事件设置到connection && ET模式 
        SetNonBlock(_listensock->Fd());             //文件描述符设置为非阻塞(ET模式)
    }

    void Recver() override  //收
    {
        InetAddr client;
        while(true)//ET模式循环读文件描述符
        {   //这个文件描述符是正常文件描述符
            int sockfd=_listensock->Accept(&client);
            if(sockfd==ACCEPTDONE)
                break;
            else if(sockfd==ACCEPTCONTINUE)
                continue;
            else if(sockfd==ACCEPTERROR)
                break;
            else
            {
                //成功获取连接
                shared_ptr<Connection> conn=make_shared<Channel>(sockfd,client);//构造channel对象
                conn->SetEvent(EPOLLIN | EPOLLET);
                if(_handler!=nullptr)
                    conn->RegisterHandler(_handler);
                GetOwner()->AddConnection(conn);//继承基类函数 拿到reactor指针进而把channel对象添加到connection
            }
        }
    }
    void Sender() override
    {

    }
    void EXcepter() override
    {

    }
    int GetSockFd() override
    {
        return _listensock->Fd();
    }
    ~Listener()
    {

    }
private:
    unique_ptr<Socket> _listensock;
    int _port;
};